home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / AVIIndex.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  4.7 KB  |  228 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include <stdio.h>
  19. #include <crtdbg.h>
  20.  
  21. #include "AVIIndex.h"
  22.  
  23. ///////////////////////////////////////////////////////////////////////////
  24.  
  25. class AVIIndexChainNode {
  26. public:
  27.     enum { ENTS=2048 };
  28.  
  29.     AVIIndexChainNode *next;
  30.  
  31.     AVIIndexEntry2 ient[ENTS];
  32.     int num_ents;
  33.  
  34.     AVIIndexChainNode() {
  35.         num_ents = 0;
  36.         next = NULL;
  37.     }
  38.  
  39.     bool add(FOURCC ckid, __int64 pos, long size, bool is_keyframe) {
  40.         if (num_ents < ENTS) {
  41.             ient[num_ents].ckid = ckid;
  42.             ient[num_ents].pos = pos;
  43.             ient[num_ents].size = is_keyframe ? size : 0x80000000+size;
  44.             ++num_ents;
  45.             return true;
  46.         }
  47.         return false;
  48.     }
  49.  
  50.     void put(AVIINDEXENTRY *&avieptr) {
  51.         int i;
  52.  
  53.         for(i=0; i<num_ents; i++) {
  54.             avieptr->ckid            = ient[i].ckid;
  55.             avieptr->dwFlags        = ient[i].size & 0x80000000 ? 0 : AVIIF_KEYFRAME;
  56.             avieptr->dwChunkOffset    = ient[i].pos;
  57.             avieptr->dwChunkLength    = ient[i].size & 0x7FFFFFFF;
  58.  
  59.             ++avieptr;
  60.         }
  61.     }
  62.  
  63.     void put(AVIIndexEntry2 *&avie2ptr) {
  64.         int i;
  65.  
  66.         for(i=0; i<num_ents; i++)
  67.             *avie2ptr++ = ient[i];
  68.     }
  69.  
  70.     void put(AVIIndexEntry3 *&avie3ptr, __int64 offset) {
  71.         int i;
  72.  
  73.         for(i=0; i<num_ents; i++) {
  74.             avie3ptr->dwSizeKeyframe    = ient[i].size;
  75.             avie3ptr->dwOffset            = (DWORD)(ient[i].pos - offset);
  76.  
  77.             ++avie3ptr;
  78.         }
  79.     }
  80. };
  81.  
  82. ///////////////////////////////////////////////////////////////////////////
  83.  
  84. AVIIndexChain::AVIIndexChain() {
  85.     head = tail = NULL;
  86.     total_ents = 0;
  87. }
  88.  
  89. void AVIIndexChain::delete_chain() {
  90.     AVIIndexChainNode *aicn = head,*aicn2;
  91.  
  92.     while(aicn) {
  93.         aicn2 = aicn->next;
  94.         delete aicn;
  95.         aicn = aicn2;
  96.     }
  97.  
  98.     head = tail = NULL;
  99. }
  100.  
  101. AVIIndexChain::~AVIIndexChain() {
  102.     delete_chain();
  103. }
  104.  
  105. bool AVIIndexChain::add(AVIINDEXENTRY *avie) {
  106.     if (!tail || !tail->add(avie->ckid, avie->dwChunkOffset, avie->dwChunkLength, !!(avie->dwFlags & AVIIF_KEYFRAME))) {
  107.         AVIIndexChainNode *aicn = new AVIIndexChainNode();
  108.  
  109.         if (tail) tail->next = aicn; else head=aicn;
  110.         tail = aicn;
  111.  
  112.         if (tail->add(avie->ckid, avie->dwChunkOffset, avie->dwChunkLength, !!(avie->dwFlags & AVIIF_KEYFRAME))) {
  113.             ++total_ents;
  114.             return true;
  115.         }
  116.  
  117.         return false;
  118.     }
  119.  
  120.     ++total_ents;
  121.  
  122.     return true;
  123. }
  124.  
  125. bool AVIIndexChain::add(AVIIndexEntry2 *avie2) {
  126.     return add(avie2->ckid, avie2->pos, avie2->size & 0x7FFFFFFF, !!(avie2->size & 0x80000000));
  127. }
  128.  
  129. bool AVIIndexChain::add(FOURCC ckid, __int64 pos, long size, bool is_keyframe) {
  130.     if (!tail || !tail->add(ckid, pos, size, is_keyframe)) {
  131.         AVIIndexChainNode *aicn = new AVIIndexChainNode();
  132.  
  133.         if (tail) tail->next = aicn; else head=aicn;
  134.         tail = aicn;
  135.  
  136.         if (tail->add(ckid, pos, size, is_keyframe)) {
  137.             ++total_ents;
  138.             return true;
  139.         }
  140.  
  141.         return false;
  142.     }
  143.  
  144.     ++total_ents;
  145.  
  146.     return true;
  147. }
  148.  
  149. void AVIIndexChain::put(AVIINDEXENTRY *avietbl) {
  150.     AVIIndexChainNode *aicn = head;
  151.  
  152.     while(aicn) {
  153.         aicn->put(avietbl);
  154.         aicn=aicn->next;
  155.     }
  156.  
  157.     delete_chain();
  158. }
  159.  
  160. void AVIIndexChain::put(AVIIndexEntry2 *avie2tbl) {
  161.     AVIIndexChainNode *aicn = head;
  162.  
  163.     while(aicn) {
  164.         aicn->put(avie2tbl);
  165.         aicn=aicn->next;
  166.     }
  167.  
  168.     delete_chain();
  169. }
  170.  
  171. void AVIIndexChain::put(AVIIndexEntry3 *avie3tbl, __int64 offset) {
  172.     AVIIndexChainNode *aicn = head;
  173.  
  174.     while(aicn) {
  175.         aicn->put(avie3tbl, offset);
  176.         aicn=aicn->next;
  177.     }
  178.  
  179.     delete_chain();
  180. }
  181.  
  182. AVIIndex::AVIIndex() {
  183.     index = NULL;
  184.     index2 = NULL;
  185.     index3 = NULL;
  186. }
  187.  
  188. AVIIndex::~AVIIndex() {
  189.     delete[] index;
  190.     delete[] index2;
  191.     delete[] index3;
  192. }
  193.  
  194. bool AVIIndex::makeIndex() {
  195.     if (!allocateIndex(total_ents)) return false;
  196.  
  197.     put(indexPtr());
  198.  
  199.     return true;
  200. }
  201.  
  202. bool AVIIndex::makeIndex2() {
  203.     if (!allocateIndex2(total_ents)) return false;
  204.  
  205.     put(index2Ptr());
  206.  
  207.     return true;
  208. }
  209.  
  210. bool AVIIndex::makeIndex3(__int64 offset) {
  211.     if (!allocateIndex3(total_ents)) return false;
  212.  
  213.     put(index3Ptr(), offset);
  214.  
  215.     return true;
  216. }
  217.  
  218. void AVIIndex::clear() {
  219.     delete_chain();
  220.     delete[] index;
  221.     delete[] index2;
  222.     delete[] index3;
  223.     index = NULL;
  224.     index2 = NULL;
  225.     index3 = NULL;
  226.     total_ents = 0;
  227. }
  228.